﻿namespace TriangleGames.TrainResEditor
{
    using TriangleGames.TrainRes;
    using System;
    using System.Collections.Generic;
    using UnityEditor;
    using UnityEngine;

    public class FsmSelector : EditorWindow
    {
        private static bool autoScroll;
        private FsmBrowserMode browserMode;
        private const float CheckBoxWidth = 20f;
        private readonly List<Fsm> filteredList = new List<Fsm>();
        private float fsmColumnWidth;
        private static FsmSelector instance;
        private Fsm lastSelectedFsm;
        private Vector2 scrollPosition;
        private float scrollViewHeight;
        private static Rect selectedRect;
        private bool showFullPath;

        private void BuildFilteredList()
        {
            this.filteredList.Clear();
            this.showFullPath = true;
            if (this.browserMode == FsmBrowserMode.RecentlySelected)
            {
                foreach (Fsm fsm in FsmEditor.RecentlySelectedList)
                {
                    this.filteredList.Add(fsm);
                }
            }
            else
            {
                foreach (Fsm fsm2 in FsmEditor.SortedFsmList)
                {
                    switch (this.browserMode)
                    {
                        case FsmBrowserMode.All:
                            this.filteredList.Add(fsm2);
                            break;

                        case FsmBrowserMode.OnSelectedObject:
                            if (fsm2.GameObject == FsmEditor.SelectedFsmGameObject)
                            {
                                this.filteredList.Add(fsm2);
                            }
                            this.showFullPath = false;
                            break;

                        case FsmBrowserMode.WithErrors:
                            if (FsmErrorChecker.FsmHasErrors(fsm2))
                            {
                                this.filteredList.Add(fsm2);
                            }
                            break;
                    }
                }
            }
            base.Repaint();
        }

        private void DoAutoScroll()
        {
            if ((FsmEditor.SelectedFsm != null) && ((Event.current.type == EventType.Repaint) && autoScroll))
            {
                this.scrollViewHeight = GUILayoutUtility.GetLastRect().height;
                if (selectedRect.y < 0f)
                {
                    this.scrollPosition.y += selectedRect.y;
                    base.Repaint();
                }
                else if ((selectedRect.y + selectedRect.height) > this.scrollViewHeight)
                {
                    this.scrollPosition.y += (selectedRect.y + selectedRect.height) - this.scrollViewHeight;
                    base.Repaint();
                }
                autoScroll = false;
            }
        }

        private void DoFsmRow(Fsm fsm)
        {
            if ((fsm != null) && (fsm.Owner != null))
            {
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                fsm.Owner.enabled = GUILayout.Toggle(fsm.Owner.enabled, new GUIContent("", "激活"), FsmEditorStyles.TableRowCheckBox, new GUILayoutOption[] { GUILayout.MaxWidth(17f) });
                string fullFsmLabel = FsmEditorUtility.GetFullFsmLabel(fsm);
                GUIContent content = new GUIContent("", fullFsmLabel);
                if (FsmEditorSettings.FsmBrowserShowFullPath && this.showFullPath)
                {
                    content.text = fullFsmLabel;
                }
                else
                {
                    content.text = FsmEditorUtility.GetFsmLabel(fsm);
                }
                GUIContent content2 = new GUIContent();
                if (GameStateTracker.CurrentState == GameState.Stopped)
                {
                    content2.text = fsm.StartState;
                }
                else
                {
                    content2.text = (fsm.ActiveState == null) ? "[没有激活粘贴]" : fsm.ActiveState.Name;
                }
                content2.tooltip = content2.text;
                switch (FsmEditorGUILayout.TableRow(new GUIContent[] { content, content2 }, new float[] { 0.6f, 0.4f }, FsmEditor.SelectedFsm == fsm, FsmErrorChecker.FsmHasErrors(fsm), new GUILayoutOption[0]))
                {
                    case 0:
                        FsmEditor.SelectFsm(fsm);
                        GUIUtility.ExitGUI();
                        break;

                    case 1:
                        FsmEditor.SelectFsm(fsm);
                        FsmEditor.SelectStateByName(content2.text);
                        GUIUtility.ExitGUI();
                        break;
                }
                GUILayout.EndHorizontal();
                if ((fsm == FsmEditor.SelectedFsm) && (Event.current.type == EventType.Repaint))
                {
                    selectedRect = GUILayoutUtility.GetLastRect();
                    selectedRect.y -= this.scrollPosition.y;
                }
            }
        }

        private void DoTableHeader()
        {
            GUILayout.BeginHorizontal(FsmEditorStyles.TableRowBox, new GUILayoutOption[0]);
            GUILayout.Toggle(false, new GUIContent("", "激活"), FsmEditorStyles.TableRowHeader, new GUILayoutOption[] { GUILayout.MaxWidth(16f) });
            GUILayout.Toggle(false, new GUIContent("状态机", ""), FsmEditorStyles.TableRowHeader, new GUILayoutOption[] { GUILayout.MaxWidth(this.fsmColumnWidth) });
            GUILayout.Toggle(false, new GUIContent("粘贴", "开始/当前状态"), FsmEditorStyles.TableRowHeader, new GUILayoutOption[0]);
            GUILayout.EndHorizontal();
        }

        private void DoToolbar()
        {
            GUILayout.BeginHorizontal(EditorStyles.toolbar, new GUILayoutOption[0]);
            FsmBrowserMode mode = (FsmBrowserMode) EditorGUILayout.EnumPopup(this.browserMode, EditorStyles.toolbarPopup, new GUILayoutOption[0]);
            if (this.browserMode != mode)
            {
                this.SetMode(mode);
            }
            if (FsmEditorGUILayout.ToolbarSettingsButton())
            {
                this.GenerateSettingsMenu().ShowAsContext();
            }
            GUILayout.Space(-10f);
            GUILayout.EndHorizontal();
        }

        private GenericMenu GenerateSettingsMenu()
        {
            GenericMenu menu = new GenericMenu();
            menu.AddItem(new GUIContent("显示状态机的全局路径"), FsmEditorSettings.FsmBrowserShowFullPath, new GenericMenu.MenuFunction(this.ToggleShowFullPath));
            return menu;
        }

        private void HandleKeyboardInput()
        {
            if (GUIUtility.keyboardControl == 0)
            {
                int controlID = GUIUtility.GetControlID(FocusType.Keyboard);
                if (Event.current.GetTypeForControl(controlID) == EventType.KeyDown)
                {
                    switch (Event.current.keyCode)
                    {
                        case KeyCode.UpArrow:
                            Event.current.Use();
                            this.SelectPrevious();
                            GUIUtility.ExitGUI();
                            return;

                        case KeyCode.DownArrow:
                            Event.current.Use();
                            this.SelectNext();
                            GUIUtility.ExitGUI();
                            return;
                    }
                }
            }
        }

        private void OnDisable()
        {
            if (instance == this)
            {
                instance = null;
            }
            this.filteredList.Clear();
        }

        private void OnEnable()
        {
            instance = this;
            base.title = "状态机浏览器";
            base.minSize = new Vector2(200f, 100f);
            base.autoRepaintOnSceneChange = true;
            this.BuildFilteredList();
        }

        private void OnFocus()
        {
            this.BuildFilteredList();
        }

        private void OnGUI()
        {
            if (FsmEditorGUILayout.ToolWindowsCommonGUI(this))
            {
                if (((Event.current.type == EventType.MouseDown) && (Event.current.button == 0)) && (GUIUtility.hotControl == 0))
                {
                    GUIUtility.keyboardControl = 0;
                }
                this.fsmColumnWidth = (base.position.width - 20f) * 0.6f;
                this.HandleKeyboardInput();
                this.DoToolbar();
                this.DoTableHeader();
                this.scrollPosition = GUILayout.BeginScrollView(this.scrollPosition, new GUILayoutOption[0]);
                if (this.filteredList.Count == 0)
                {
                    GUILayout.BeginHorizontal(FsmEditorStyles.TableRowBox, new GUILayoutOption[0]);
                    GUILayout.Label("     [空]", new GUILayoutOption[0]);
                    GUILayout.EndHorizontal();
                }
                foreach (Fsm fsm in this.filteredList)
                {
                    this.DoFsmRow(fsm);
                }
                GUILayout.EndScrollView();
                this.DoAutoScroll();
                FsmEditorGUILayout.Divider(new GUILayoutOption[0]);
                if (FsmEditor.SelectedFsm != null)
                {
                    FsmEditor.SelectedFsm.Description = EditorGUILayout.TextArea(FsmEditor.SelectedFsm.Description, FsmEditorStyles.TextArea, new GUILayoutOption[] { GUILayout.MinHeight(44f) });
                    EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
                    FsmEditor.SelectedFsm.DocUrl = EditorGUILayout.TextField(FsmEditor.SelectedFsm.DocUrl, new GUILayoutOption[0]);
                    if (string.IsNullOrEmpty(FsmEditor.SelectedFsm.DocUrl))
                    {
                        GUI.enabled = false;
                    }
                    if (FsmEditorGUILayout.HelpButton("在线帮助"))
                    {
                        Application.OpenURL(FsmEditor.SelectedFsm.DocUrl);
                    }
                    EditorGUILayout.EndHorizontal();
                }
                else
                {
                    GUI.enabled = false;
                    GUILayout.TextArea("描述...", new GUILayoutOption[] { GUILayout.MinHeight(44f) });
                    EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
                    GUILayout.TextField("文档链接", new GUILayoutOption[0]);
                    FsmEditorGUILayout.HelpButton("在线帮助");
                    EditorGUILayout.EndHorizontal();
                }
                EditorGUILayout.Space();
            }
        }

        public static void Refresh()
        {
            if (instance != null)
            {
                instance.BuildFilteredList();
            }
        }

        private void SelectNext()
        {
            if (FsmEditor.SelectedFsm != null)
            {
                int index = this.filteredList.IndexOf(FsmEditor.SelectedFsm);
                if (index < (this.filteredList.Count - 1))
                {
                    FsmEditor.SelectFsm(this.filteredList[index + 1]);
                }
                autoScroll = true;
            }
        }

        private void SelectPrevious()
        {
            if (FsmEditor.SelectedFsm != null)
            {
                int index = this.filteredList.IndexOf(FsmEditor.SelectedFsm);
                if (index > 0)
                {
                    FsmEditor.SelectFsm(this.filteredList[index - 1]);
                }
                autoScroll = true;
            }
        }

        public void SetMode(FsmBrowserMode mode)
        {
            this.browserMode = mode;
            this.BuildFilteredList();
        }

        private void ToggleShowFullPath()
        {
            FsmEditorSettings.FsmBrowserShowFullPath = !FsmEditorSettings.FsmBrowserShowFullPath;
            FsmEditorSettings.SaveSettings();
            base.Repaint();
        }

        private void Update()
        {
            if (FsmEditor.Instance == null)
            {
                base.Close();
            }
            else if (!FsmEditorSettings.DisableEditorWhenPlaying && (this.lastSelectedFsm != FsmEditor.SelectedFsm))
            {
                this.lastSelectedFsm = FsmEditor.SelectedFsm;
                autoScroll = true;
                base.Repaint();
            }
        }

        public enum FsmBrowserMode
        {
            All,
            OnSelectedObject,
            RecentlySelected,
            WithErrors
        }
    }
}

